package org.lundberg.podcasts;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;

import org.lundberg.podcasts.util.PodcastDB;
import org.lundberg.podcasts.util.Util;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;

public class UpdateService extends Service implements OnSharedPreferenceChangeListener
{
	public static final String UPDATED = "org.lundberg.podcasts.UPDATED";
	public static final String UPDATE = "org.lundberg.podcasts.UPDATE";
	public static final String CLEARED = "org.lundberg.podcasts.CLEARED";
	//private static final int REFRESH_NOTIFICATION_ID = 3;
	//private static final int NEW_ITEMS_NOTIFICATION_ID = 4;
	
	private static boolean updating = false;
	private PendingIntent pendingIntent;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	
	@Override
	public void onCreate()
	{
		Log.d("UpdateService", "onCreate");
		
		// Set up a listener to be notified of changes to the keep_old_items preference
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        settings.registerOnSharedPreferenceChangeListener(this);
	}
	
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		Log.d("UpdateService", "onStartCommand");
        
		if (!updating)
		{
			int channelID = -1;
			final boolean forceUpdate = (intent == null) ? false : intent.getBooleanExtra("force_update", false);
			
			// Update *some* channels
			if (intent != null && intent.hasExtra("channel")) {
				
				channelID = intent.getIntExtra("channel", -1);
			}
			
			new UpdateThread(channelID, forceUpdate).start();
		}
		
		return START_STICKY;
	}
	
	
	
	private void setUpdateTimer(long lastUpdateTime)
	{
		if (pendingIntent == null) {
			Intent intent = new Intent(getApplicationContext(), UpdateService.class);
			pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		}
		
		AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
		
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		long frequency = Integer.parseInt(settings.getString(PodcastPreferenceActivity.UPDATE_FREQ_PREF, "8")) * 3600000;
        long nextUpdateTime = lastUpdateTime + frequency;
		
        double relative = (nextUpdateTime-System.currentTimeMillis())/3600000.0;
		Log.d("UpdateService", "Scheduling alarm - lastUpdate: "+lastUpdateTime+"; nextUpdate: "+nextUpdateTime
				+" ("+String.format("%.2f", relative)+" hours from now)");
		
		alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTime, pendingIntent);
		
		// Save the last_update time
        Editor editor = settings.edit();
    	editor.putLong(PodcastPreferenceActivity.LAST_UPDATE_PREF, lastUpdateTime);
    	editor.commit();
	}
	
	
	
	
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		Log.d("UpdateService", "onDestroy");
	}

	
	
	@Override
	public void onSharedPreferenceChanged(SharedPreferences sp, String key)
	{
		if (PodcastPreferenceActivity.UPDATE_FREQ_PREF.equals(key))
		{
			long frequency = Integer.parseInt(sp.getString(PodcastPreferenceActivity.UPDATE_FREQ_PREF, "8")) * 3600000;
			
			Log.d("UpdateService", "onSharedPreferenceChanged - frequency: "+frequency);
			
			long lastUpdateTime = sp.getLong(PodcastPreferenceActivity.LAST_UPDATE_PREF, System.currentTimeMillis());
			
			Log.d("UpdateService", "onSharedPreferenceChanged("+key+") - "
									+"lastUpdateTime: "+lastUpdateTime
									+" ;frequency: "+frequency);
			
			// Reset the timer for the new frequency
			setUpdateTimer(lastUpdateTime);
		}
	}
	
	
	
	private static class TempFileFilter implements FilenameFilter
    {
		@Override
		public boolean accept(File arg0, String arg1) {

			if (arg1.endsWith(".tmp")) {
				return true;
			}

			return false;
		}
    }
	
	
	
	private class UpdateThread extends Thread
	{
		private int channelID;
		private boolean forceUpdate;
		
		private UpdateThread(int channelID, boolean forceUpdate)
		{
			this.channelID = channelID;
			this.forceUpdate = forceUpdate;
		}
		
		public void run()
		{
			updating = true;
			
			SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
			long frequency = Integer.parseInt(settings.getString(PodcastPreferenceActivity.UPDATE_FREQ_PREF, "8")) * 3600000;
	        long lastUpdateTime = settings.getLong(PodcastPreferenceActivity.LAST_UPDATE_PREF, System.currentTimeMillis());
			long now = System.currentTimeMillis();
			long delta = (now - lastUpdateTime);
			boolean shouldUpdate = (delta > frequency);
			
	    	Log.d("UpdateService", "update - lastUpdateTime: "+lastUpdateTime
	    									+"; now: "+now
	    									+"; frequency: "+frequency
	    									+"; delta: "+delta
	    									+"; update: "+(shouldUpdate || forceUpdate));
	
	    	if (shouldUpdate || forceUpdate)
	    	{
	    		// update the time the podcasts were last refreshed
	    		lastUpdateTime = now;
		    	
		        String maxOldItems = settings.getString(PodcastPreferenceActivity.KEEP_OLD_ITEMS_PREF, "5");
		        
		    	PodcastDB helper = new PodcastDB(getApplicationContext());
		    	SQLiteDatabase db = helper.getReadableDatabase();
		
		    	String where = (channelID > -1) ? "_id="+channelID : null;
		    	
		    	// Get a list of channels from the database
			    Cursor c = db.query(true, PodcastDB.CHANNELS_TABLE, new String[] {"_id", "title", "url"},
			                             where, null, null, null, "title", null);
			        
			    int numChannels = c.getCount();
			    c.moveToFirst();
			    
			    for (int i=0; i < numChannels; i++, c.moveToNext())
			    {
			    	int id = c.getInt(0);
		        	//String title = c.getString(1);
		        	String url = c.getString(2);
					
					//newItemCount += PodcastDB.addRefresh(getApplicationContext(), channel.url);
					PodcastDB.addRefresh(getApplicationContext(), url);
					
					PodcastDB.deleteOldItems(getApplicationContext(), id, maxOldItems);
			    }
		        
		        c.close();
		    	helper.close();
		        
		        
		        // Delete old temp files
		    	File dir = Util.getCacheDir();
		    	for (File file : dir.listFiles(new TempFileFilter()))
		    	{
		    		long modTime = file.lastModified();
		    		
		    		// if the file is more than 7 days old
		    		if ((now - modTime) > 604800000) {
		    			file.delete();
		    		}
		    	}
		        
		    	
		        ArrayList<String> newItems = PodcastDB.getNewItems(getApplicationContext());
		        
		        
	        	Intent updatedIntent = new Intent(UPDATED);
	        	updatedIntent.putExtra("count", newItems.size());
		        sendBroadcast(updatedIntent);
	        	Editor editor = settings.edit();
	        	editor.putInt(PodcastPreferenceActivity.NEW_ITEM_COUNT_PREF, newItems.size());
	        	editor.commit();
	        	
		        // If there's wifi, automatically start downloading new items
				if (newItems.isEmpty() == false && Util.isWiFiAvailable(getApplicationContext()))
				{
					Intent downloadIntent = new Intent(getApplicationContext(), DownloadService.class);
					downloadIntent.setAction(DownloadService.DOWNLOAD);
					downloadIntent.putExtra("guid", newItems);
					startService(downloadIntent);
				}
		        
	    	}
	    	
	        
	        // Schedule the next update
	    	setUpdateTimer(lastUpdateTime);
	    
			// Reset the updating flag
	    	updating = false;
		}
	}

}
